package com.zhala.system.service.impl;

import com.zhala.common.core.domain.CommonResult;
import com.zhala.common.exception.ServiceException;
import com.zhala.common.utils.DateUtils;
import com.zhala.common.utils.StringUtils;
import com.zhala.common.utils.uuid.IdUtils;
import com.zhala.system.domain.ZlSteelBigPipe;
import com.zhala.system.domain.ZlSteelPipe;
import com.zhala.system.domain.vo.*;
import com.zhala.system.mapper.ZlSteelBigPipeMapper;
import com.zhala.system.mapper.ZlSteelPipeMapper;
import com.zhala.system.service.CommonService;
import com.zhala.system.service.IZlSteelBigPipeService;
import com.zhala.system.service.IZlSteelPipeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 管接大组Service业务层处理
 *
 * @author ruoyi
 * @date 2024-11-11
 */
@Service
public class ZlSteelBigPipeServiceImpl implements IZlSteelBigPipeService {
    @Autowired
    private ZlSteelBigPipeMapper zlSteelBigPipeMapper;
    @Autowired
    private CommonService commonService;
    @Autowired
    private ZlSteelPipeMapper zlSteelPipeMapper;
    @Autowired
    private IZlSteelPipeService zlSteelPipeService;

    public CommonResult<Boolean> rollBack(PipeRollBackReqVO reqVO) {
        //大管情况
        ZlSteelBigPipe bigPipe = zlSteelBigPipeMapper.selectById(reqVO.getId());
        if (bigPipe != null) {
            if (!bigPipe.getProcedure().equals(reqVO.getProcedure())) {
                return CommonResult.error("当前单据所处工序已发生更改，请刷新后重试");
            }
            if (bigPipe.getProcedure() == 7) {
                return CommonResult.error("当前单据所处工序不可回退，请刷新后重试");
            }
            if (bigPipe.getProcedure() <= 7) {
                return CommonResult.error("当前单据所处工序异常，请刷新后重试");
            }
            bigPipe.setProcedure(reqVO.getProcedure() - 1);
            bigPipe.setStatus(0);
            zlSteelBigPipeMapper.updateZlSteelBigPipe(bigPipe);
            return CommonResult.success(true);
        }
        //小管情况
        ZlSteelPipe pipe = zlSteelPipeMapper.selectById(reqVO.getId());
        if (pipe != null) {
            if (!pipe.getProcedure().equals(reqVO.getProcedure())) {
                return CommonResult.error("当前单据所处工序已发生更改，请刷新后重试");
            }
            if (pipe.getProcedure() == 1) {
                return CommonResult.error("当前单据所处工序不可回退，请刷新后重试");
            }
            if (pipe.getProcedure() >= 7) {
                return CommonResult.error("当前单据所处工序异常，请刷新后重试");
            }
            pipe.setProcedure(reqVO.getProcedure() - 1);
            pipe.setStatus(0);
            zlSteelPipeMapper.updateZlSteelPipe(pipe);
            return CommonResult.success(true);
        }
        return CommonResult.error("当前单据不存在");
    }

    /**
     * 查询管接大组
     *
     * @param CREATOR 管接大组主键
     * @return 管接大组
     */
    @Override
    public ZlSteelBigPipe selectZlSteelBigPipeByCREATOR(String CREATOR) {
        return zlSteelBigPipeMapper.selectZlSteelBigPipeByCREATOR(CREATOR);
    }

    /**
     * 查询管接大组列表
     *
     * @param zlSteelBigPipe 管接大组
     * @return 管接大组
     */
    @Override
    public List<ZlSteelBigPipe> selectZlSteelBigPipeList(ZlSteelBigPipe zlSteelBigPipe) {
        return zlSteelBigPipeMapper.selectZlSteelBigPipeList(zlSteelBigPipe);
    }

    /**
     * 新增管接大组
     *
     * @param zlSteelBigPipe 管接大组
     * @return 结果
     */
    @Override
    public int insertZlSteelBigPipe(ZlSteelBigPipe zlSteelBigPipe) {
        zlSteelBigPipe.setCreateTime(DateUtils.getNowDate());
        return zlSteelBigPipeMapper.insertZlSteelBigPipe(zlSteelBigPipe);
    }

    /**
     * 修改管接大组
     *
     * @param zlSteelBigPipe 管接大组
     * @return 结果
     */
    @Override
    public int updateZlSteelBigPipe(ZlSteelBigPipe zlSteelBigPipe) {
        zlSteelBigPipe.setUpdateTime(DateUtils.getNowDate());
        return zlSteelBigPipeMapper.updateZlSteelBigPipe(zlSteelBigPipe);
    }

    /**
     * 批量删除管接大组
     *
     * @param CREATORs 需要删除的管接大组主键
     * @return 结果
     */
    @Override
    public int deleteZlSteelBigPipeByCREATORs(String[] CREATORs) {
        return zlSteelBigPipeMapper.deleteZlSteelBigPipeByCREATORs(CREATORs);
    }

    /**
     * 删除管接大组信息
     *
     * @param CREATOR 管接大组主键
     * @return 结果
     */
    @Override
    public int deleteZlSteelBigPipeByCREATOR(String CREATOR) {
        return zlSteelBigPipeMapper.deleteZlSteelBigPipeByCREATOR(CREATOR);
    }

    /**
     * 管节大组
     * 该方法负责将用户提交的钢管设置请求信息持久化到数据库中
     * 使用了事务注解，确保数据库操作的原子性
     *
     * @param reqVO 钢管设置请求对象，包含了用户提交的设置信息
     * @return 返回一个通用结果对象，表示设置操作是否成功
     */
    @Override
    @Transactional
    public CommonResult<Boolean> settingsUpdate(SteelBigPipeReqVO reqVO) {
        List<ZlSteelPipe> steelPipeList = zlSteelPipeMapper.listUsed(reqVO.getPipeList());
        if (!CollectionUtils.isEmpty(steelPipeList)) {
            return CommonResult.error("小管已使用[" + steelPipeList.get(0).getPipeNum() + "],请刷新列表稍后再试！");
        }
        //获取小管编号
        String pipeNums = zlSteelPipeMapper.getPipeNums(reqVO.getPipeList());
        if (StringUtils.isBlank(pipeNums)) {
            return CommonResult.error("小管信息不存在");
        }
        String material = zlSteelPipeMapper.getPipeMaterial(reqVO.getPipeList());
        // 创建一个中联钢管对象，用于存储请求信息到数据库
        ZlSteelBigPipe zlSteelBigPipe = new ZlSteelBigPipe();
        // 使用Spring的工具类复制请求对象的属性到中联钢管对象
        BeanUtils.copyProperties(reqVO, zlSteelBigPipe);
        // 为中联钢管对象设置一个唯一的ID
        zlSteelBigPipe.setId(IdUtils.fastUUID());
        // 设置未删除状态
        zlSteelBigPipe.setDeleted(false);
        zlSteelBigPipe.setPipeNum(pipeNums);
        zlSteelBigPipe.setMaterial(material);
        zlSteelBigPipe.setStatus(0);
        zlSteelBigPipe.setProcedure(6);
        // 调用公共服务初始化中联钢管对象的其他属性
        commonService.initPojo(zlSteelBigPipe);
        // 插入中联钢管对象到数据库
        zlSteelBigPipeMapper.insertZlSteelBigPipe(zlSteelBigPipe);
        // 更新数据库中相关小钢管的关联ID
        zlSteelPipeMapper.setBigPipeId(zlSteelBigPipe.getId(), reqVO.getPipeList());
        // 返回成功结果
        return CommonResult.success(true);
    }

    /**
     * 管节大组
     * 该方法负责将用户提交的钢管设置请求信息持久化到数据库中
     * 使用了事务注解，确保数据库操作的原子性
     *
     * @param reqVO 钢管设置请求对象，包含了用户提交的设置信息
     * @return 返回一个通用结果对象，表示设置操作是否成功
     */
    @Override
    @Transactional
    public CommonResult<Boolean> settings(SteelBigPipeReqVO reqVO) {
        Boolean toAddSteelPipe = true;
        ZlSteelBigPipe zlSteelBigPipe = new ZlSteelBigPipe();
        // 为中联钢管对象设置一个唯一的ID
        String id = IdUtils.fastUUID();
        zlSteelBigPipe.setId(id);
        if (StringUtils.isNotBlank(reqVO.getId())) {
            // 验证请求的合法性并获取对应的钢管对象
            zlSteelBigPipe = this.validate(reqVO.getId());
            // 查询并设置与大口径钢管相关的小口径钢管列表
            List<SteelPipeRespVO> steelPipeList = zlSteelPipeService.listByPipeId(reqVO.getId());
            if (!CollectionUtils.isEmpty(steelPipeList) && steelPipeList.size() > 1) {
                toAddSteelPipe = false;
            }
        }
        if (toAddSteelPipe) {
            List<ZlSteelPipe> steelPipeList = zlSteelPipeMapper.listUsed(reqVO.getPipeList());
            if (!CollectionUtils.isEmpty(steelPipeList)) {
                return CommonResult.error("小管已使用[" + steelPipeList.get(0).getPipeNum() + "],请刷新列表稍后再试！");
            }
            //获取小管编号
            String pipeNums = zlSteelPipeMapper.getPipeNums(reqVO.getPipeList());
            if (StringUtils.isBlank(pipeNums)) {
                return CommonResult.error("小管信息不存在");
            }
            String material = zlSteelPipeMapper.getPipeMaterial(reqVO.getPipeList());
            zlSteelBigPipe.setPipeNum(pipeNums);
            zlSteelBigPipe.setMaterial(material);
            zlSteelBigPipe.setStatus(0);
            zlSteelBigPipe.setProcedure(8);
            // 更新数据库中相关小钢管的关联ID
            zlSteelPipeMapper.setBigPipeId(zlSteelBigPipe.getId(), reqVO.getPipeList());
        }
        // 使用Spring的工具类复制请求对象的属性到中联钢管对象
        BeanUtils.copyProperties(reqVO, zlSteelBigPipe);
        // 设置未删除状态
        zlSteelBigPipe.setDeleted(false);
        // 调用公共服务初始化中联钢管对象的其他属性
        commonService.initPojo(zlSteelBigPipe);
        if(StringUtils.isBlank(reqVO.getId())){
            zlSteelBigPipe.setId(id);
            // 插入中联钢管对象到数据库
            zlSteelBigPipeMapper.insertZlSteelBigPipe(zlSteelBigPipe);
        }else {
            zlSteelBigPipe.setStatus(0);
            zlSteelBigPipe.setProcedure(7);
            zlSteelBigPipeMapper.updateZlSteelBigPipe(zlSteelBigPipe);
        }
        // 返回成功结果
        return CommonResult.success(true);
    }

    /**
     * 执行环焊缝焊接操作
     * <p>
     * 此方法负责处理环焊缝焊接的请求，更新数据库中的相关信息，并记录操作者和操作时间
     *
     * @param reqVO 环焊缝焊接请求对象，包含焊接用户的ID、焊接开始和结束时间等信息
     * @return 返回一个CommonResult对象，包含操作结果的布尔值，true表示成功
     */
    @Override
    public CommonResult<Boolean> girthWeld(SteelBigPipeGirtWeldReqVO reqVO, Boolean isUpdate) {
        // 验证请求的合法性并获取对应的钢管对象
        ZlSteelBigPipe zlSteelBigPipe = this.validate(reqVO.getId());

        // 设置环焊缝焊接用户
        zlSteelBigPipe.setGirthWeldUser(reqVO.getGirthWeldUser());
        // 设置环焊缝焊接开始时间
        zlSteelBigPipe.setGirthWeldStartTime(reqVO.getGirthWeldStartTime());
        // 设置环焊缝焊接结束时间
        zlSteelBigPipe.setGirthWeldEndTime(reqVO.getGirthWeldEndTime());
        if (!isUpdate) {
            // 设置初始工序代码
            zlSteelBigPipe.setProcedure(8);
        }
        // 记录处理环焊缝焊接请求的操作者昵称
        zlSteelBigPipe.setGirthWeldDealUser(commonService.getUserNickName());

        // 更新数据库中的钢管对象信息
        commonService.updatePojo(zlSteelBigPipe);
        // 调用Mapper层方法，执行数据库更新操作
        zlSteelBigPipeMapper.updateZlSteelBigPipe(zlSteelBigPipe);

        // 返回操作成功的结果
        return CommonResult.success(true);
    }


    /**
     * 处管节调圆
     *
     * @param reqVO 请求对象，包含大管道环向焊接的相关信息
     * @return 返回一个通用结果对象，表示操作是否成功
     */
    @Override
    public CommonResult<Boolean> pipeCircular(BigPipeCircularReqVO reqVO) {
        // 验证请求ID的合法性，并获取对应的钢管对象
        ZlSteelBigPipe zlSteelBigPipe = this.validate(reqVO.getId());
        // 设置处理当前环向焊接的用户昵称
        zlSteelBigPipe.setBigPipeCircularDealUser(commonService.getUserNickName());
        // 设置环向焊接的结束时间
        zlSteelBigPipe.setBigPipeCircularEndTime(reqVO.getBigPipeCircularEndTime());
        // 设置初始工序代码
        zlSteelBigPipe.setProcedure(9);
        // 更新数据库中的钢管对象信息
        commonService.updatePojo(zlSteelBigPipe);
        // 调用Mapper层方法，执行数据库更新操作
        zlSteelBigPipeMapper.updateZlSteelBigPipe(zlSteelBigPipe);
        // 返回操作成功的结果
        return CommonResult.success(true);
    }


    /**
     * 加固环形件处理
     * <p>
     * 此方法用于处理大口径管道的加固环形件请求它首先验证请求的合法性，
     * 然后更新数据库中的相关记录，并返回处理结果
     *
     * @param reqVO 请求视图对象，包含加固环形件所需的参数
     * @return 返回一个CommonResult对象，包含处理结果的布尔值
     */
    @Override
    public CommonResult<Boolean> stiffenRing(BigPipeStiffenRingReqVO reqVO) {
        // 验证请求的合法性，包括检查ID是否对应有效的记录
        ZlSteelBigPipe zlSteelBigPipe = this.validate(reqVO.getId());
        zlSteelBigPipe.setStiffenRingEndTime(reqVO.getStiffenRingEndTime());
        // 设置当前处理用户的昵称，用于追踪责任
        zlSteelBigPipe.setStiffenRingDealUser(commonService.getUserNickName());
        // 设置初始工序代码
        zlSteelBigPipe.setProcedure(10);
        // 更新数据库中的记录
        commonService.updatePojo(zlSteelBigPipe);
        // 调用Mapper层方法，执行数据库更新操作
        zlSteelBigPipeMapper.updateZlSteelBigPipe(zlSteelBigPipe);
        // 返回操作成功的结果
        return CommonResult.success(true);
    }


    /**
     * 加固环焊缝处理方法
     * 该方法用于更新大口径钢管的加固环焊缝相关信息，包括结束时间和操作用户
     *
     * @param reqVO 包含加固环焊缝操作请求数据的对象
     * @return 返回一个通用结果对象，包含操作是否成功的布尔值
     */
    @Override
    public CommonResult<Boolean> stiffenRingWeld(BigPipeStiffenRingWeldReqVO reqVO) {
        // 验证请求的合法性，包括检查ID是否对应有效的记录
        ZlSteelBigPipe zlSteelBigPipe = this.validate(reqVO.getId());
        // 设置加固环焊缝的结束时间
        zlSteelBigPipe.setStiffenRingWeldEndTime(reqVO.getStiffenRingWeldEndTime());
        // 设置执行加固环焊缝操作的用户
        zlSteelBigPipe.setStiffenRingWeldUser(reqVO.getStiffenRingWeldUser());
        // 设置当前处理用户的昵称，用于追踪责任
        zlSteelBigPipe.setStiffenRingWeldDealUser(commonService.getUserNickName());
        // 设置初始工序代码
        zlSteelBigPipe.setProcedure(11);
        // 更新数据库中的记录
        commonService.updatePojo(zlSteelBigPipe);
        // 调用Mapper层方法，执行数据库更新操作
        zlSteelBigPipeMapper.updateZlSteelBigPipe(zlSteelBigPipe);
        // 返回操作成功的结果
        return CommonResult.success(true);
    }


    /**
     * 处理验收操作
     * 此方法接收一个BigPipeAcceptanceReqVO对象作为请求参数，验证并更新数据库中的验收信息
     * 它首先验证请求的合法性，然后将请求数据复制到数据库模型中，
     * 设置验收处理用户和时间，最后更新数据库记录并返回成功结果
     *
     * @param reqVO 验收请求对象，包含验收所需的信息
     * @return 返回一个CommonResult对象，包含操作结果的布尔值
     */
    @Override
    public CommonResult<Boolean> acceptance(BigPipeAcceptanceReqVO reqVO) {
        // 验证请求的合法性并获取对应的数据库记录
        ZlSteelBigPipe zlSteelBigPipe = this.validate(reqVO.getId());
        // 将请求参数中的属性复制到数据库模型中，以便后续更新数据库
        BeanUtils.copyProperties(reqVO, zlSteelBigPipe);
        // 设置验收处理的用户昵称
        zlSteelBigPipe.setAcceptanceDealUser(commonService.getUserNickName());
        // 设置当前的验收时间
        zlSteelBigPipe.setAcceptanceTime(new Date());
        // 设置初始工序代码
        zlSteelBigPipe.setProcedure(12);
        // 更新数据库中的记录
        commonService.updatePojo(zlSteelBigPipe);
        // 调用Mapper层方法，执行数据库更新操作
        zlSteelBigPipeMapper.updateZlSteelBigPipe(zlSteelBigPipe);
        // 返回操作成功的结果
        return CommonResult.success(true);
    }

    /**
     * 执行大管验收处理
     * 此方法首先验证请求的合法性，然后更新数据库中的相应记录，以表示验收处理的过程和结果
     *
     * @param reqVO 包含验收处理请求信息的对象
     * @return 返回一个CommonResult对象，包含操作是否成功的布尔值
     */
    @Override
    public CommonResult<Boolean> antisepsis(BigPipeAntisepsisReqVO reqVO, Boolean isUpdate) {
        // 验证请求的合法性并获取对应的数据库记录
        ZlSteelBigPipe zlSteelBigPipe = this.validate(reqVO.getId());
        // 将请求参数中的属性复制到数据库模型中，以便后续更新数据库
        BeanUtils.copyProperties(reqVO, zlSteelBigPipe);
        // 设置验收处理的用户昵称
        zlSteelBigPipe.setAntisepsisDealUser(commonService.getUserNickName());
        // 设置当前的验收时间
        zlSteelBigPipe.setAntisepsisDealTime(new Date());
        // 设置初始工序代码
        if (!isUpdate) {
            zlSteelBigPipe.setProcedure(-1);
            // 设置记录为已验收状态
            zlSteelBigPipe.setStatus(1);
        }
        // 更新数据库中的记录
        commonService.updatePojo(zlSteelBigPipe);
        // 调用Mapper层方法，执行数据库更新操作
        zlSteelBigPipeMapper.updateZlSteelBigPipe(zlSteelBigPipe);
        // 返回操作成功的结果
        return CommonResult.success(true);
    }

    /**
     * 处理废品操作
     *
     * @param reqVO 废品操作的请求对象，包含废品操作的相关信息
     * @return 返回一个CommonResult对象，包含操作结果的布尔值
     */
    @Override
    public CommonResult<Boolean> scrap(PipeScrapReqVO reqVO) {
        // 验证请求的合法性并获取对应的数据库记录
        ZlSteelBigPipe zlSteelBigPipe = this.validate(reqVO.getId());
        // 设置管道的状态为废品状态，状态码2代表废品
        zlSteelBigPipe.setStatus(2);
        // 更新数据库中的记录
        commonService.updatePojo(zlSteelBigPipe);
        // 调用Mapper层方法，执行数据库更新操作
        zlSteelBigPipeMapper.updateZlSteelBigPipe(zlSteelBigPipe);
        // 返回操作成功的结果
        return CommonResult.success(true);
    }

    /**
     * 获取大口径钢管的信息
     *
     * @param id   钢管的唯一标识符
     * @param type 钢管的类型
     * @return 包含大口径钢管信息的CommonResult对象
     */
    @Override
    public CommonResult<SteelBigPipeRespVO> info(String id, Integer type) {
        // 验证钢管信息的合法性
        ZlSteelBigPipe bigPipe = this.validate(id);
        // 创建响应视图对象，并将大口径钢管的基本信息复制到该对象中
        SteelBigPipeRespVO respVO = new SteelBigPipeRespVO();
        BeanUtils.copyProperties(bigPipe, respVO);
        // 查询并设置与大口径钢管相关的小口径钢管列表
        List<SteelPipeRespVO> steelPipeList = zlSteelPipeService.listByPipeId(id);
        respVO.setSteelPipeList(steelPipeList);
        if (type != null && type == 1) {
            respVO.setTimeLineList(this.buildTimeLine(respVO.getSteelPipeList(), bigPipe));
        }
        // 返回成功的结果，包含大口径钢管及其相关小口径钢管的信息
        return CommonResult.success(respVO);
    }

    /**
     * 构建时间线
     * 根据提供的钢管响应列表和大管道对象，创建一系列时间线对象，用于展示关键事件的时间
     *
     * @param steelPipeList 钢管响应列表，包含每个钢管的相关信息
     * @param bigPipe       大管道对象，包含大管道的施工和状态信息
     * @return 返回一个时间线对象列表，每个对象代表一个关键事件及其时间
     */
    private List<TimeLineVO> buildTimeLine(List<SteelPipeRespVO> steelPipeList, ZlSteelBigPipe bigPipe) {
        // 初始化时间线列表
        List<TimeLineVO> list = new ArrayList<>();

        // 遍历钢管列表，为每个完成的钢管添加时间线项
        for (SteelPipeRespVO pipe : steelPipeList) {
            list.add(new TimeLineVO("管节(" + pipe.getPipeNum() + ")完成", pipe.getWeldEndTime()));
        }
        // 检查并添加大管道完成的时间线项
        if (bigPipe.getBigPipeEndTime() != null) {
            list.add(new TimeLineVO("管节大组", bigPipe.getBigPipeEndTime()));
        }
        // 检查并添加环形焊接完成的时间线项
        if (bigPipe.getGirthWeldEndTime() != null) {
            list.add(new TimeLineVO("环形焊接", bigPipe.getGirthWeldEndTime()));
        }
        // 检查并添加管节调圆完成的时间线项
        if (bigPipe.getBigPipeCircularEndTime() != null) {
            list.add(new TimeLineVO("管节调圆", bigPipe.getBigPipeCircularEndTime()));
        }
        // 检查并添加加劲环安装完成的时间线项
        if (bigPipe.getStiffenRingEndTime() != null) {
            list.add(new TimeLineVO("加劲环安装", bigPipe.getStiffenRingEndTime()));
        }
        // 检查并添加加劲环焊接完成的时间线项
        if (bigPipe.getStiffenRingWeldEndTime() != null) {
            list.add(new TimeLineVO("加劲环焊接", bigPipe.getStiffenRingWeldEndTime()));
        }
        // 检查并添加验收完成的时间线项
        if (bigPipe.getAntisepsisEndTime() != null) {
            list.add(new TimeLineVO("验收", bigPipe.getAntisepsisEndTime()));
        }
        // 检查并添加节管防腐处理完成的时间线项
        if (bigPipe.getAntisepsisDealTime() != null) {
            list.add(new TimeLineVO("节管防腐", bigPipe.getAntisepsisDealTime()));
        }
        // 检查管道状态，如果是报废状态，则添加报废的时间线项
        if (bigPipe.getStatus() != null && bigPipe.getStatus() == 2) {
            list.add(new TimeLineVO("报废", bigPipe.getUpdateTime()));
        }
        // 返回构建好的时间线列表
        return list;
    }


    /**
     * 根据ID验证大管信息的存在性
     *
     * @param id 大管信息的唯一标识符
     * @return 如果大管信息存在，则返回对应的ZlSteelBigPipe对象
     * @throws ServiceException 如果大管信息不存在，则抛出服务异常
     */
    public ZlSteelBigPipe validate(String id) {
        // 通过ID查询大管信息
        ZlSteelBigPipe zlSteelBigPipe = zlSteelBigPipeMapper.selectById(id);

        // 如果查询结果为空，则抛出异常提示信息不存在
        if (zlSteelBigPipe == null) {
            throw new ServiceException(443, "大管信息不存在");
        }

        // 返回查询到的大管信息
        return zlSteelBigPipe;
    }


}
